package com.tankgame4;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

import static java.lang.Thread.sleep;

/**
 * 坦克大战绘图区
 */
// 为了监听键盘事件 实现KeyListener
public class MyPanel extends JPanel implements KeyListener, Runnable{
    // 定义我的坦克
    Hero hero = null;

    // 定义敌人坦克
    Vector<EnemyTank> enemyTanks = new Vector<>();
    // 用于恢复敌方坦克的位置信息
    Vector<Node> nodes = new Vector<>();
    // 定义用于放炸弹
    Vector<Bomb> bombs = new Vector<>();

    // 定义三张图片用于显示爆炸效果
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;

    int enemyTankSize = 4;
    public MyPanel(String key) {
        nodes = Recorder.getNodesAndEnemyTankRec();

        // 将MyPanel的enemyTanks的值赋给Recorder的enemyTanks
        Recorder.setEnemyTanks(enemyTanks);

        hero = new Hero(500, 100); // 初始化自己坦克

        switch (key) {
            case "1": // 新游戏
                Recorder.setAllEnemyTankNum(0);
                // 初始化敌人坦克
                for (int i = 0; i < enemyTankSize; i++) {
                    // 创建一个敌人的坦克
                    EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
                    // 设置坦克的方向
                    enemyTank.setDirect(2);
                    // 将enemyTank设置给setEnemyTanks
                    enemyTank.setEnemyTanks(enemyTanks);
                    // 启动敌人坦克线程
                    new Thread(enemyTank).start();
                    // 给该坦克加入一颗子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    enemyTank.shots.add(shot);
                    // 启动Shot线程
                    new Thread(shot).start();
                    // 加入enemyTank的Vector成员
                    enemyTanks.add(enemyTank);

                }
                break;
            case "2": // 继续游戏
                // 初始化敌人坦克
                for (int i = 0; i < nodes.size(); i++) {
                    Node node = nodes.get(i);
                    // 创建一个敌人的坦克
                    EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
                    // 设置坦克的方向
                    enemyTank.setDirect(node.getDirect());
                    // 将enemyTank设置给setEnemyTanks
                    enemyTank.setEnemyTanks(enemyTanks);
                    // 启动敌人坦克线程
                    new Thread(enemyTank).start();
                    // 给该坦克加入一颗子弹
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    enemyTank.shots.add(shot);
                    // 启动Shot线程
                    new Thread(shot).start();
                    // 加入enemyTank的Vector成员
                    enemyTanks.add(enemyTank);

                }
                break;
            default:
                System.out.println("你的输入有误");
        }



        // 初始化图片对象
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb1.png"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb2.gif"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb3.gif"));

        // 加载背景音乐
        new AePlayWave("src\\tank.wav").start();

    }

    // 显示我方击毁敌方坦克的信息
    public void showInfo(Graphics g) {
        // 画出玩家信息
        g.setColor(Color.BLACK);
        Font font = new Font("宋体", Font.BOLD, 25);
        g.setFont(font);
        g.drawString("您累计击毁敌方坦克数：", 1020, 30);
        drawTank(1020, 60, g, 0, 0); // 画出敌方坦克标志
        g.setColor(Color.BLACK);
        g.drawString(Recorder.getAllEnemyTankNum() + "", 1080, 100);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 1000, 750);
        showInfo(g);
        // 画出己方坦克-封装方法
        if (hero != null && hero.isLive) {
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);


            // 画出hero射击的子弹
            for (int i = 0; i < hero.shots.size(); i++) {
                Shot shot = hero.shots.get(i);
                if (shot != null && shot.isLive) {
                    g.fill3DRect(shot.x, shot.y, 3, 1, false);
                } else {
                    hero.shots.remove(shot);
                }
            }
        }





        // 为了防止第一个不爆炸 添加一个延时
        try {
            sleep(10);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 如果Bomb中有对象 就画出
        for (int i = 0; i < bombs.size(); i++) {
            // 取出炸弹
            Bomb bomb = bombs.get(i);
            // 根据当前bomb对象的life值去画出对应的图片
            if (bomb.life > 6) {
                g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
            } else if (bomb.life > 3) {
                g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
            } else {
                g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
            }

            // 让炸弹生命值减少
            bomb.lifeDown();
            // 判断bomb life的值
            if (bomb.life == 0) {
                bombs.remove(bomb);
            }

        }

        // 画出敌人坦克
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            // 判断当前敌人坦克是否存活
            if (enemyTank.isLive) {
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);
                // 画出敌人坦克已经发射的所有子弹
                for (int j = 0; j < enemyTank.shots.size(); j++) {
                    // 取出子弹
                    Shot shot = enemyTank.shots.get(j);
                    // 绘制
                    if (shot.isLive) {
                        g.fill3DRect(shot.x, shot.y, 3, 1, false);
                    } else {
                        enemyTank.shots.remove(shot);
                    }
                }
            }
        }
    }

    // 判断hero是否被击中
    public void wasHeroShot() {
        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            for (int j = 0; j < enemyTank.shots.size(); j++) {
                Shot shot = enemyTank.shots.get(j);
                if (shot != null && shot.isLive && hero.isLive) {
                    hitTank(shot, hero);
                }
            }
        }
    }
    // 判断enemyTank是否被击中
    public void wasEnemyShot() {
        for (int j = 0; j < hero.shots.size(); j++) {
            Shot shot = hero.shots.get(j);
            if (shot != null && shot.isLive) {
                // 遍历敌人所有坦克
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    hitTank(shot, enemyTank);
                }
            }
        }
    }

    // 编写方法 画出坦克
    /**
     *
     * @param x 坦克的左上角的横坐标
     * @param y 左上角的纵坐标
     * @param g 画笔
     * @param direct 坦克方向（上下左右）
     * @param type 坦克类型
     */
    public void drawTank(int x, int y, Graphics g, int direct, int type) {

        // 根据不同类型坦克 设置坦克为不同的颜色
        switch (type) {
            case 0: // 敌人的坦克
                g.setColor(Color.CYAN);
                break;
            case 1: // 我们的坦克
                g.setColor(Color.YELLOW);
                break;
        }

        // 根据坦克方向来绘制坦克
        // direct （0：向上 1：向右 2：向下 3：向左）
        switch (direct) {
            case 0: // 表示向上
                g.fill3DRect(x, y, 10, 60, false); // 画出坦克左边的轮子
                g.fill3DRect(x + 30, y, 10, 60, false); // 画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false); // 画出坦克的中间部分
                g.fillOval(x + 10, y + 20, 20, 20); // 画出坦克的炮台
                g.drawLine(x + 20, y + 30, x + 20, y); // 画出坦克的炮管
                break;
            case 1: // 表示向右
                g.fill3DRect(x, y, 60, 10, false); // 画出坦克上边的轮子
                g.fill3DRect(x, y + 30, 60, 10, false); // 画出坦克下边的轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false); // 画出坦克的中间部分
                g.fillOval(x + 20, y + 10, 20, 20); // 画出坦克的炮台
                g.drawLine(x + 30, y + 20, x + 60, y + 20); // 画出坦克的炮管
                break;
            case 2: // 表示向下
                g.fill3DRect(x, y, 10, 60, false); // 画出坦克左边的轮子
                g.fill3DRect(x + 30, y, 10, 60, false); // 画出坦克右边的轮子
                g.fill3DRect(x + 10, y + 10, 20, 40, false); // 画出坦克的中间部分
                g.fillOval(x + 10, y + 20, 20, 20); // 画出坦克的炮台
                g.drawLine(x + 20, y + 30, x + 20, y + 60); // 画出坦克的炮管
                break;
            case 3: // 表示向左
                g.fill3DRect(x, y, 60, 10, false); // 画出坦克上边的轮子
                g.fill3DRect(x, y + 30, 60, 10, false); // 画出坦克下边的轮子
                g.fill3DRect(x + 10, y + 10, 40, 20, false); // 画出坦克的中间部分
                g.fillOval(x + 20, y + 10, 20, 20); // 画出坦克的炮台
                g.drawLine(x + 30, y + 20, x, y + 20); // 画出坦克的炮管
                break;

        }
    }

    // 编写方法判断子弹是否击中坦克
    public void hitTank(Shot shot, Tank tank) {
        // 判断s 击中坦克
        switch (tank.getDirect()) {
            case 0: // 坦克向上
                if (shot.x > tank.getX() && shot.x < tank.getX() + 40 && shot.y > tank.getY()
                        && shot.y < tank.getY() + 60) {
                    shot.isLive = false;
                    tank.isLive = false;
                    // 如果被射击的是敌人
                    if (tank instanceof EnemyTank) {
                        hero.shots.remove(shot);
                        enemyTanks.remove(tank);
                        Recorder.addAllEnemyTankNum();
                    } else if (tank instanceof Hero) {
//                        hero = null;
//                        System.out.println("up: " + hero);

                    }
                    // 创建一个 Bomb对象，加入Bomb集合
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                }
                break;
            case 1: // 坦克向右
                if (shot.x > tank.getX() && shot.x < tank.getX() + 60 && shot.y > tank.getY()
                        && shot.y < tank.getY() + 40) {
                    shot.isLive = false;
                    tank.isLive = false;
                    // 如果被射击的是敌人
                    if (tank instanceof EnemyTank) {
                        hero.shots.remove(shot);
                        enemyTanks.remove(tank);
                        Recorder.addAllEnemyTankNum();
                    } else if (tank instanceof Hero) {
//                        hero = null;
//                        System.out.println("right: " + hero);


                    }
                    // 创建一个Bomb对象，加入Bomb集合
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                }
                break;
            case 2: // 坦克向下
                if (shot.x > tank.getX() && shot.x < tank.getX() + 40 && shot.y > tank.getY()
                && shot.y < tank.getY() + 60) {
                    shot.isLive = false;
                    tank.isLive = false;
                    // 如果被射击的是敌人
                    if (tank instanceof EnemyTank) {
                        hero.shots.remove(shot);
                        enemyTanks.remove(tank);
                        Recorder.addAllEnemyTankNum();
                    } else if (tank instanceof Hero) {
//                        hero = null;
//                        System.out.println("down: " + hero);


                    }
                    // 创建一个Bomb对象，加入Bomb集合
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                }
                break;
            case 3: // 坦克向左
                if (shot.x > tank.getX() && shot.x < tank.getX() + 60 && shot.y > tank.getY()
                        && shot.y < tank.getY() + 40) {
                    shot.isLive = false;
                    tank.isLive = false;
                    // 如果被射击的是敌人
                    if (tank instanceof EnemyTank) {
                        hero.shots.remove(shot);
                        enemyTanks.remove(tank);
                        Recorder.addAllEnemyTankNum();
                    } else if (tank instanceof Hero) {
//                        hero = null;
//                        System.out.println("left: " + hero);


                    }
                    // 创建一个Bomb对象，加入Bomb集合
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                }
                break;
        }
    }



    @Override
    public void keyTyped(KeyEvent e) {

    }
    // 处理wsad方向键
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W && hero != null) {
            hero.setDirect(0);
            if (hero.getY() > 0) {
                hero.moveUp();
            }

        } else if (e.getKeyCode() == KeyEvent.VK_D && hero != null) {
            hero.setDirect(1);
            if (hero.getX() + 60 < 1000) {
                hero.moveRight();
            }

        } else if (e.getKeyCode() == KeyEvent.VK_S && hero != null) {
            hero.setDirect(2);
            if (hero.getY() + 60 < 750) {
                hero.moveDown();
            }

        } else if (e.getKeyCode() == KeyEvent.VK_A && hero != null) {
            hero.setDirect(3);
            if (hero.getX() > 0) {
                hero.moveLeft();
            }

        }

        // 如果用户按下的是J键，就发射子弹
        if (e.getKeyCode() == KeyEvent.VK_J && hero != null) {
            hero.shotEnemyTank();
        }

        // 让面板重绘
        this.repaint();
    }



    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() { // 重绘区域 每个100ms
        while (true) {
            try {
                sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 判断是否击中了敌人坦克
            wasEnemyShot();

            // 判断是否击中了hero坦克
            if (hero != null) {
                System.out.println("run() " + hero);
                wasHeroShot();
            }

            this.repaint();
        }
    }
}
